/*
 * Copyright (c) 2004-2012 Loren M Halvorson
 * This source is subject to the Microsoft Public License (Ms-PL).
 * See http://www.microsoft.com/resources/sharedsource/licensingbasics/publiclicense.mspx.
 * All other rights reserved.
 * Portions copyright 2002-2007 The Genghis Group (http://www.genghisgroup.com/)
 * Portions copyright 2007-08 Thomas F. Abraham.
 */

using System;
using System.Collections;
using System.ComponentModel;
using System.Configuration.Install;

namespace XmlPreprocess
{
    /// <summary>
    /// Installer class to support deployment of configuration files
    /// via the InstallUtil.exe utility.
    /// </summary>
    [RunInstaller(true)]
    public class XmlInstaller : System.Configuration.Install.Installer
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.Container components = null;

        /// <summary>
        ///
        /// </summary>
        public XmlInstaller()
        {
            InitializeComponent();
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="stateSaver"></param>
        public override void Install(System.Collections.IDictionary  stateSaver)
        {
            base.Install(stateSaver);

#if NOFIXFALSE
            bool fixFalse = false;
#else
            bool fixFalse = true;
#endif
            if (Context.Parameters.ContainsKey("f"))
                fixFalse = true;

            PreprocessingContext ctx = new PreprocessingContext(fixFalse);

            // get the parameters from the command line
            string propFile = null;
            if (Context.Parameters.ContainsKey("s") && Context.Parameters["s"].Length > 0)
                propFile = Context.Parameters["s"];

            if (Context.Parameters.ContainsKey("i")	&& Context.Parameters["i"].Length > 0)
                ctx.SourceFile = Context.Parameters["i"];

            if (Context.Parameters.ContainsKey("o") && Context.Parameters["o"].Length > 0)
                ctx.DestinationFile = Context.Parameters["o"];

            ctx.PreserveMarkup = true;
            if (Context.Parameters.ContainsKey("c"))
                ctx.PreserveMarkup = false;

            // parse the property file
            if (null != propFile && propFile.Length > 0)
            {
                try
                {
                    ctx.Properties.ReadFromFile(propFile, null);
                }
                catch (System.Xml.XmlException xe)
                {
                    throw new InstallException("Error parsing " + propFile + ": " + xe.Message + " at line " + xe.LineNumber, xe);
                }
                catch (Exception e)
                {
                    throw new InstallException("Error parsing " + propFile, e);
                }
            }

            // parse additional command line properties
            ArrayList a = new ArrayList();
            foreach (string key in Context.Parameters.Keys)
            {
                if (key.StartsWith("d:"))
                {
                    string property = null;
                    string val = Context.Parameters[key];
                    if (null == val || 0 == val.Length)
                        property = key.Substring(2);
                    else
                        property = key.Substring(2) + "=" + val;

                    a.Add(property);
                }
            }

            ctx.Properties.AddPropertiesFromArrayList(ctx, a);

            Console.WriteLine(string.Format("Preprocessing {0} to {1}...",ctx.SourceFile, ctx.DestinationFile));

            XmlPreprocessor preprocessor = new XmlPreprocessor();

            try
            {
                preprocessor.Preprocess(ctx);
            }
            catch (Exception e)
            {
                throw new InstallException(string.Format("Error encountered preprocessing {0}", ctx.SourceFile), e);
            }
        }


        #region Component Designer generated code
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            components = new System.ComponentModel.Container();
        }
        #endregion
    }
}
